import { memo, useCallback } from 'react';
import type { FC, PropsWithChildren } from 'react';
import {
  Control,
  SubmitHandler,
  useForm,
  UseFormTrigger,
} from 'react-hook-form';
import {
  Button,
  Form,
  FormItemProps,
  InputProps,
  message,
  Tooltip,
  TooltipProps,
} from 'antd';
import * as yup from 'yup';
import { alphaNumericRegexString, phoneRegexString } from '@/constants/regexp';
import { useAuthStore } from '@/store/authStore';
import { yupResolver } from '@hookform/resolvers/yup';
import QueueAnim from 'rc-queue-anim';
import RxButton from '@/components/RxForm/RxButton';
import RxCodeInput from '@/components/RxForm/RxCodeInput';
import RxEmailCode from '@/components/RxForm/RxEmailCode';
import RxInput from '@/components/RxForm/RxInput';
import RxPassword from '@/components/RxForm/RxPassword';
import RxRadio from '@/components/RxForm/RxRadio';
import { RadioItem } from '@/components/typing';
import { tooltip } from '@/pages/Login/components/EmailRegisterForm';
import { formatPhone } from '@/utils/format';

const schema = yup
  .object({
    account: yup
      .string()
      .when('way', (way, schema) => {
        return way === 'phone'
          ? schema.matches(phoneRegexString, '手机格式错误')
          : schema.email();
      })
      .required(),
    way: yup.string().oneOf(['phone', 'email']).required(),
    password: yup
      .string()
      .matches(alphaNumericRegexString, '密码只能包含数字和字母')
      .min(8)
      .max(16),
    passwordConfirmation: yup
      .string()
      .oneOf([yup.ref('password')], '确认密码错误')
      .required(),
    code: yup.string().required(),
  })
  .required();

const defaultValues: API.ResetPasswordParams = {
  account: '',
  way: 'phone',
  password: '',
  passwordConfirmation: '',
  code: '',
};

const CodeInput: FC<
  PropsWithChildren<
    Partial<InputProps> & {
      isPhoneCode: boolean;
      name: string;
      control: Control<any>;
      item?: FormItemProps;
      trigger: UseFormTrigger<any>;
    }
  >
> = ({ isPhoneCode, ...rest }) => {
  // @ts-ignore
  return isPhoneCode ? (
    <RxCodeInput {...rest} triggerName={'account'} />
  ) : (
    <RxEmailCode {...rest} triggerName={'account'} />
  );
};

const ResetPasswordForm: FC<PropsWithChildren<{ show?: boolean }>> = ({
  show,
}) => {
  const { control, handleSubmit, trigger, resetField, reset, watch } =
    useForm<API.ResetPasswordParams>({
      resolver: yupResolver(schema),
      defaultValues,
      mode: 'all',
      criteriaMode: 'all',
    });

  const { resetPassword } = useAuthStore();
  const { handler, loading } = resetPassword();
  const onsubmit: SubmitHandler<API.ResetPasswordParams> = useCallback(
    (values) => {
      if (!values.account.includes('@')) {
        values.account = formatPhone(values.account);
      }
      handler(values)
        .then(() => {
          reset();
        })
        .finally(() => {
          resetField('code');
        })
        .catch(() => {
          message.error('服务器错误，重置密码失败');
        });
    },
    []
  );
  const componentProps = {
    onFinish: handleSubmit(onsubmit),
    className: 'w-72 h-72',
  };

  const radioItem: RadioItem[] = [
    {
      value: 'phone',
      label: '手机',
    },
    {
      value: 'email',
      label: '邮箱',
    },
  ];

  return !show ? null : (
    <QueueAnim
      leaveReverse
      //@ts-ignore
      component={Form}
      componentProps={componentProps}
    >
      {show
        ? [
            <RxRadio
              radioItem={radioItem}
              key={'way'}
              name={'way'}
              control={control}
            />,
            <RxInput
              key={'account'}
              name={'account'}
              placeholder={'手机号/邮箱'}
              control={control}
              // addonBefore="+86"
            />,
            <RxPassword
              key={'password'}
              name={'password'}
              placeholder={'请输入新密码'}
              control={control}
              tooltip={tooltip}
            />,
            <RxPassword
              key={'passwordConfirmation'}
              name={'passwordConfirmation'}
              placeholder={'确认密码'}
              control={control}
              tooltip={tooltip}
            />,
            <div key={'code'}>
              <CodeInput
                isPhoneCode={watch('way') === 'phone'}
                name={'code'}
                placeholder={'验证码'}
                control={control}
                trigger={trigger}
              />
            </div>,
            <div key={'submit'}>
              <RxButton loading={loading} />
            </div>,
          ]
        : null}
    </QueueAnim>
  );
};

export default memo(ResetPasswordForm);
